package com.bucket.cloud.system.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.bucket.cloud.common.core.model.Attributes;
import com.bucket.cloud.common.core.model.JsonTreeData;
import com.bucket.cloud.common.core.mybatisPlus.query.CriteriaQuery;
import com.bucket.cloud.common.core.util.TreeNodeUtil;
import com.bucket.cloud.system.api.model.*;
import com.bucket.cloud.system.api.util.MenuTreeUtil;
import com.bucket.cloud.system.dao.ResourcesMapper;
import com.bucket.cloud.system.service.ResourcesService;
import com.bucket.cloud.system.service.RoleResourcesService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;


@Service
@Transactional
public class ResourcesServiceImpl implements ResourcesService {
    @Resource
    private ResourcesMapper resourcesMapper;
    @Autowired
    private RoleResourcesService roleResourcesService;

    @Override
    public void deleteResources(String[] id) {
        resourcesMapper.deleteBatchIds(Arrays.asList(id));
        roleResourcesService.deleteByResourcesId(id);
    }

    @Override
    public void insertResources(SystemResources systemResources) {
        resourcesMapper.insert(systemResources);
    }

    @Override
    public void updateResources(SystemResources systemResources) {
        resourcesMapper.updateById(systemResources);
    }

    @Override
    public List<JsonTreeData> findResources(SystemResources resources) {
        CriteriaQuery params = new CriteriaQuery<SystemResources>();
        if (StringUtils.isNotBlank(resources.getType()))
            params.like("type", resources.getType());
        if (resources.getState() != null)
            params.eq("state", resources.getState());
        params.orderByAsc("sort");
        List systemResourcesList = resourcesMapper.selectList(params);
        return resourcesToJsonTreeData(systemResourcesList);
    }

    @Override
    public IPage<SystemResources> findResourcesPage(ResourcesPage resourcesPage) {
        IPage pageObj = new Page(resourcesPage.getPageNumber(), resourcesPage.getPageSize());
        return resourcesMapper.queryByParams(pageObj, resourcesPage);
    }

    @Override
    public void enableResources(String[] id, int state) {
        for (String i : id) {
            SystemResources rs = new SystemResources();
            rs.setId(i);
            rs.setState(state);
            resourcesMapper.updateById(rs);
        }

    }

    @Override
    public List<JsonTreeData> queryUserResources(SystemUser systemUser) {
        systemUser.setState(1);// 作为获取未禁用权限的参数，并不是查询用户状态
        return resourcesToJsonTreeData(resourcesMapper.queryUserResources(systemUser));
    }

    @Override
    public List<SystemMenu> getAllMenuList(SystemResources resources) {
        CriteriaQuery params = new CriteriaQuery<SystemResources>();
        if (StringUtils.isNotBlank(resources.getType())) {
            params.like("type", resources.getType());
        }
        if (resources.getState() != null) {
            params.eq("state", resources.getState());
        }
        if (StringUtils.isNotBlank(resources.getName())) {
            params.like("name", resources.getName());
        }
        if (StringUtils.isNotBlank(resources.getPid())) {
            params.eq("pid", resources.getPid());
        }
        params.orderByAsc("sort");
        List systemResourcesList = resourcesMapper.selectList(params);
        return resourcesToMenuTreeData(systemResourcesList);
    }

    @Override
    public SystemResources queryInfo(SystemResources param) {
        QueryWrapper<SystemResources> queryWrapper = new QueryWrapper();
        queryWrapper.lambda()
                .eq(ObjectUtils.isNotEmpty(param.getId()), SystemResources::getId, param.getId());
        return resourcesMapper.selectOne(queryWrapper);
    }

    @Override
    public List<SystemResources> queryBtnList(Map<String, Object> param) {
        return resourcesMapper.selectByMap(param);
    }

    private List<JsonTreeData> resourcesToJsonTreeData(List<SystemResources> systemResourcesList) {
        List<JsonTreeData> treeDataList = new ArrayList<JsonTreeData>();
        /*为了整理成公用的方法，所以将查询结果进行二次转换。
         * 其中specid为主键ID，varchar类型UUID生成
         * parentid为父ID
         * specname为节点名称
         * */
        for (SystemResources htSpecifications : systemResourcesList) {
            JsonTreeData treeData = new JsonTreeData(htSpecifications.getId()
                    , htSpecifications.getPid(), htSpecifications.getName()
                    , null, htSpecifications.getState()
                    , new Attributes(htSpecifications.getUrl(), htSpecifications.getCode(),
                    htSpecifications.getType(), htSpecifications.getBtnClass())
                    , null);
            treeDataList.add(treeData);
        }
        //最后得到结果集,经过FirstJSON转换后就可得所需的json格式
        List<JsonTreeData> newTreeDataList = TreeNodeUtil.getfatherNode(treeDataList);
        return newTreeDataList;
    }

    private List<SystemMenu> resourcesToMenuTreeData(List<SystemResources> systemResourcesList) {
        List<SystemMenu> treeDataList = new ArrayList<SystemMenu>();
        /*为了整理成公用的方法，所以将查询结果进行二次转换。
         * 其中specid为主键ID，varchar类型UUID生成
         * parentid为父ID
         * specname为节点名称
         * */
        for (SystemResources s : systemResourcesList) {
            SystemMenu treeData = new SystemMenu(s.getId(), s.getPid(), s.getSort(), s.getName(), true, null, s.getUrl(), s.getCode(), s.getType(), s.getState());
            treeDataList.add(treeData);
        }
        //最后得到结果集,经过FirstJSON转换后就可得所需的json格式
        List<SystemMenu> newTreeDataList = MenuTreeUtil.getfatherNode(treeDataList);
        return newTreeDataList;
    }

}
